﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace Util
{
    /// <summary>
    /// A simple implementation of the batch manager suitable for single threaded batch processing
    /// </summary>
    public class PooledBatchManager: IBatchManager
    {
        private String batchFile;
        private int skip;
        //private File processingFile;

    //    private static File topDir = new File("tests");
    //    private static File inputDir = new File(topDir, "ToRun");
    //    private static File inProcessDir = new File(topDir, "InProcess");
    //    private static File completedDir = new File(topDir, "Completed");
    //    private static File resultsDir = new File(topDir, "Results");
    //    private static File lockFile = new File(".lock");
    //    private FileLock lock;
    //    private PrintStream oldOut;
    //    private FileFilter testFileFilter = new TestFileFilter();


    //    /**
    //    /// Creates a pooled batch manager
    //     *
    //    /// @param filename the name of the batch file
    //    /// @param skip     items to skip between runs
    //     */

    //    public PooledBatchManager(String filename, int skip) {
    //        this.batchFile = filename;
    //        this.skip = skip;
    //    }


    //    /** Starts processing the batch */
        public void start()
        {

    //        // redirect standard out to a file
    //        lock();
    //        try {
    //            createDirectories();
    //            redirectStdout();
    //        } finally {
    //            unlock();
    //        }
        }


    //    /**
    //    /// Gets the next available batch item or null if no more are available
    //     *
    //    /// @return the next available batch item
    //    /// @throws IOException if an I/O error occurs while reading the next item from the batch file.
    //     */
        public BatchItem getNextItem()
        {
    //        lock();
    //        try {
    //            // move the last 'in process' file to the 'completed'
    //            // tests section.

    //            if (processingFile != null) {
    //                File completedFile = getCompletedFile(processingFile);
    //                processingFile.renameTo(completedFile);
    //                processingFile = null;
    //            }
    //            File testFile = getNextFile();
    //            if (testFile != null) {
    //                processingFile = getProcessingFile(testFile);
    //                testFile.renameTo(processingFile);
    //                System.out.println("Processing: " + processingFile);
    //                return getBatchItem(processingFile);
    //            } else {
    //                return null;
    //            }
    //        } finally {
    //            unlock();
    //        }
            throw new NotImplementedException();
        }


    //    /** Stops processing the batch */
        public void stop() 
        {
    //        lock();
    //        try {
    //            closeStdout();
    //        } finally {
    //            unlock();
    //        }
        }


        /**
        /// Returns the name of the file
         *
        /// @return the filename
         */
        public String getFilename()
        {
            return batchFile;
        }


    //    /** Creates the test directories as necessary */
    //    private void createDirectories() throws IOException {
    //        if (!topDir.isDirectory()) {
    //            topDir.mkdir();
    //            inProcessDir.mkdir();
    //            completedDir.mkdir();
    //            resultsDir.mkdir();
    //            createInputDirectory();
    //        }
    //    }


    //    /** Creates the input directory */
    //    private void createInputDirectory() throws IOException {
    //        inputDir.mkdir();
    //        // read in the batch file
    //        List<String> list = BatchFile.getLines(batchFile, skip);

    //        for (int i = 0; i < list.size(); i++) {
    //            String name = Integer.toString(i + 1);
    //            String line = list.get(i);
    //            createInputFile(inputDir, name, line);
    //        }
    //    }


    //    /**
    //    /// Creates the individual batch files
    //     *
    //    /// @param dir  the directory to place the input file in
    //    /// @param name the name of the file
    //    /// @param line the contents of the file
    //     */
    //    private void createInputFile(File dir, String name, String line)
    //            throws IOException {

    //        File path = new File(dir, name);
    //        FileOutputStream fos = new FileOutputStream(path);
    //        PrintStream ps = new PrintStream(fos);
    //        ps.println(line);
    //        ps.close();
    //    }


    //    /** Redirects standard out to a file in the results directory with a name 'Results_xxx.out' */
    //    private void redirectStdout() throws IOException {
    //        String myName = getMyName();
    //        File resultFile = File.createTempFile(myName, ".out", resultsDir);

    //        FileOutputStream fos = new FileOutputStream(resultFile);
    //        PrintStream ps = new PrintStream(fos);
    //        oldOut = System.out;
    //        System.setOut(ps);

    //        System.out.println("# These results collected on " + getMyName());
    //    }


    //    /**
    //    /// Gets my network name
    //     *
    //    /// @return my network name
    //     */
    //    private String getMyName() throws IOException {
    //        return InetAddress.getLocalHost().getHostName();
    //    }


    //    /** Close the redirected stdout and restore it to what it was before we redirected it. */
    //    private void closeStdout() throws IOException {
    //        System.out.close();
    //        System.setOut(oldOut);
    //    }


    //    /** Lock the test suite so we can manipulate the set of tests */
    //    private void lock() throws IOException {
    //        RandomAccessFile raf = new RandomAccessFile(lockFile, "rw");
    //        lock = raf.getChannel().lock();
    //        raf.close();
    //    }


    //    /** unlock the test suite so we can manipulate the set of tests */
    //    private void unlock() throws IOException {
    //        lock.release();
    //        lock = null;
    //    }


    //    /**
    //    /// Given an 'in process' file, generate the corresponding completed file.
    //     *
    //    /// @param file the in process file
    //    /// @return the completed file
    //     */
    //    private File getCompletedFile(File file) {
    //        return new File(completedDir, file.getName());
    //    }


    //    /**
    //    /// Given an 'input' file, generate the corresponding inProcess file.
    //     *
    //    /// @param file the in process file
    //    /// @return the completed file
    //     */
    //    private File getProcessingFile(File file) {
    //        return new File(inProcessDir, file.getName());
    //    }


    //    /** returns the next batch item file in the input directory */
    //    private File getNextFile() throws IOException {
    //        File[] match = inputDir.listFiles(testFileFilter);

    //        if (match.length > 0) {
    //            return match[0];
    //        }
    //        return null;
    //    }


    //    /**
    //    /// Given a file parse the contents of the file into a BatchItem
    //     *
    //    /// @param file the file to parse
    //    /// @return the contents in the form of a batch item
    //     */
    //    private BatchItem getBatchItem(File file) throws IOException {
    //        List<String> list = BatchFile.getLines(file.getPath());
    //        if (list.size() != 1) {
    //            throw new IOException("Bad batch file size");
    //        }
    //        String line = list.get(0);
    //        return new BatchItem(BatchFile.getFilename(line),
    //                BatchFile.getReference(line));
    //    }
    //}

    ///** Filter that only yields filenames that are integer numbers */
    //class TestFileFilter implements FileFilter {

    //    public Boolean accept(File pathname) {
    //        String name = pathname.getName();
    //        try {
    //            Integer.parseInt(name);
    //            return true;
    //        } catch (NumberFormatException nfe) {
    //            return false;
    //        }
    //    }

    }
}
